#include <cstdlib>
#include <iostream>

#include "vector.h"

using namespace std;


Vector::Vector(const unsigned int &_row): row(_row) {
	data = new double[row];

	for(unsigned int i = 0; i < row; i++)
		data[i] = 0;
}

Vector::Vector(const Vector& _v) {
	row = _v.getRow();
	data = new double[row];

	for(unsigned int i = 0; i < row; i++)
		data[i] = _v[i];
}

Vector::~Vector() {
	delete[] data;
}

double Vector::innerProduct(const Vector & _vector) const {
	double result = 0.0;

	for(unsigned int i = 0; i < row; i++)
		result += data[i] * _vector[i];
	
	return result;
}

Matrix Vector::outterProduct(const Vector & _vector) const {
	Matrix result(row,_vector.getRow());

	for(unsigned int i = 0; i < row; i++) {
		for(unsigned int j = 0; j < _vector.getRow(); j++) {
			result[i][j] = data[i] * _vector[j];
		}
	}

	return result;
}

Vector Vector::scalarProduct(const double & _scalar) const {
	Vector result(row);

	for(unsigned int i = 0; i < row; i++) {
		result[i] = data[i]*_scalar;
	}

	return result;
}

double Vector::length() const {
	return sqrt(this->innerProduct((*this)));
}

Vector Vector::normalize() const {
	double l = this->length();
	
	if (l == 0.0) l = 1.0;
	return this->scalarProduct( 1.0/l );
}

unsigned int Vector::getRow() const {
	return row;
}

void Vector::print() {
	for(unsigned int i = 0; i < row; i++)
		cout << "| " << data[i] << " |" << endl;
}

Matrix Vector::toMatrixColumn() const {
	Matrix result(row, 1);

	for(unsigned int i = 0; i < row; i++) {
		result[i][0] = data[i];
	}

	return result;
}

double& Vector::operator[](unsigned int i) const {
	if(i >= row)
		exit(1);
	
	return data[i];
}

Vector Vector::operator-() {
	return this->scalarProduct(-1);
}

Vector& Vector::operator=(const Vector& _v1) {
	delete[] data;
	
	row = _v1.getRow();
	data = new double[row];

	for(unsigned int i = 0; i < row; i++)
		data[i] = _v1[i];

	return *this;
}

Vector operator+(const Vector& _v1, const Vector& _v2) {
	if(_v1.getRow() != _v2.getRow())
		exit(1);
	
	unsigned int nrow = _v1.getRow();

	Vector result(nrow);

	for(unsigned int i = 0; i < nrow; i++)
		result[i] = _v1[i] + _v2[i];

	return result;
}

Vector operator-(const Vector& _v1, const Vector& _v2) {
	if(_v1.getRow() != _v2.getRow())
		exit(1);
	
	unsigned int nrow = _v1.getRow();

	Vector result(nrow);

	for(unsigned int i = 0; i < nrow; i++)
		result[i] = _v1[i] - _v2[i];

	return result;
}
